#include <iostream>

#ifdef _WIN32
#include <windows.h>
#define imsleep(microsecond) Sleep(microsecond) // ms
#else
#include <unistd.h>
#define imsleep(microsecond) usleep(1000 * microsecond) // ms
#endif

#include <stdio.h> // printf

#include <vector>
#include <memory>
#include <string>
#include <sstream>
#include <fstream>
#include <iomanip>

#include "CSerialPort/SerialPort.h"
#include "CSerialPort/SerialPortInfo.h"
using namespace itas109;
using namespace std;
#include <gps.h>
#include <GPSListener.h>
#include <GCJ02.h>

GPS gps = {0};
GPS newgps = {0};

int main()
{
    CSerialPort sp;
    GPSListener listener(&sp);

    gcj02::CoordGGA gga{11410.30162, 2248.93860};
    gcj02::Coord g;

    g = gga;
    gcj02::CoordGGA gga2{g};

    cout << g << endl;
    cout << gga << endl;
    cout << gga2 << endl;

    auto gg = gcj02::WGS84ToGCJ02(g);
    cout << gg << endl;
    cout << endl;

    listener.openlog("gpslog.txt");

    printf("Version: %s\n\n", sp.getVersion());

    listener.m_availablePortsList = CSerialPortInfo::availablePortInfos();
    auto &m_availablePortsList = listener.m_availablePortsList;

    printf("AvailableFriendlyPorts:\n");

    int availablePortCount = (int)m_availablePortsList.size();

    for (int i = 1; i <= availablePortCount; ++i)
    {
        SerialPortInfo serialPortInfo = m_availablePortsList[i - 1];
        printf("%d - %s %s %s\n", i, serialPortInfo.portName, serialPortInfo.description, serialPortInfo.hardwareId);
    }

    if (m_availablePortsList.size() == 0)
    {
        printf("No valid port\n");
    }
    else
    {
        std::cout << std::endl;

        int input = -1;
        do
        {
            printf("Please Input The Index Of Port(1 - %d)\n", availablePortCount);

            std::cin >> input;

            if (input >= 1 && input <= m_availablePortsList.size())
            {
                break;
            }
        } while (true);

        const char *portName = m_availablePortsList[input - 1].portName;
        printf("Port Name: %s\n", portName);

        sp.init(portName,                // windows:COM1 Linux:/dev/ttyS0
                itas109::BaudRate115200, // baudrate
                itas109::ParityNone,     // parity
                itas109::DataBits8,      // data bit
                itas109::StopOne,        // stop bit
                itas109::FlowNone,       // flow
                4096                     // read buffer size
        );

        sp.setReadIntervalTimeout(0);         // read interval timeout 0ms
        sp.setByteReadBufferFullNotify(3276); // 4096*0.8 // buffer full notify

        sp.open();
        printf("Open %s %s\n", portName, sp.isOpen() ? "Success" : "Failed");
        printf("Code: %d, Message: %s\n", sp.getLastError(), sp.getLastErrorMsg());
        string line;

        try
        {
            //         GPS   11410.30465 E,   2248.93730 N,   0.00m   0.00m   0.00m
            cout << "\n\n          经度            纬度       定位精度  海拔高度 " << endl;
            for (;;)
            {
                imsleep(500);

                cout << "GPS   "
                     << fixed << setprecision(5) << listener.lon() << " " << listener.lon_dir() << ",   "
                     << fixed << setprecision(5) << listener.lat() << " " << listener.lat_dir() << ",   "
                     << fixed << setprecision(2) << listener.hdop() << "m     " << listener.alt() << "m   ";
                cout << endl;
            }
        }
        catch (const std::exception &e)
        {
            std::cerr << "error:" << e.what() << '\n';
        }
        catch (const char *e)
        {
            std::cerr << "error:" << e << '\n';
        }
        catch (const int e)
        {
            std::cerr << "error:" << e << '\n';
        }
    }

    return 0;
}